#pragma once
#include "Log.hpp"
#include <sys/epoll.h>
#include <stdlib.h>
#include "Comm.hpp"
class Mutip
{
public:
    virtual bool AddEvent(int fd, uint32_t ev) = 0;
    virtual bool ModEvent(int fd, uint32_t ev) = 0;
    virtual bool DelEvent(int fd) = 0;
};

class Epoller : public Mutip
{
    const static int esize = 128;
private:
    bool ModEventHelper(int fd,uint32_t ev,int oper)
    {
        struct epoll_event event;
        event.events = ev;
        event.data.fd = fd;
        int n = ::epoll_ctl(_epfd, oper, fd, &event);
        if (n < 0)
        {
            LOG(ERROR, "epoll ctl %d events:%s error\n", fd, EventsToString(ev).c_str());
            return false;
        }
        LOG(INFO, "epoll ctl %d events:%s success\n", fd, EventsToString(ev).c_str());
        return true;
    }
public:
    Epoller()
    {
        _epfd = ::epoll_create(esize);
        if (_epfd < 0)
        {
            LOG(FATAL, "create epoll error\n");
            exit(EPOLL_CREATE_ERROR);
        }
        LOG(INFO, "create epoll success,%d\n", _epfd);
    }
    std::string EventsToString(uint32_t events)
    {
        std::string eventstr;
        if (events & EPOLLIN)
            eventstr += "EPOLLIN ";
        if (events & EPOLLOUT)
            eventstr += "EPOLLOUT ";
        if (events & EPOLLET)
            eventstr += "EPOLLET ";
        return eventstr;
    }
    bool AddEvent(int fd, uint32_t ev) override
    {
        return ModEventHelper(fd, ev, EPOLL_CTL_ADD);
    }
    bool ModEvent(int fd, uint32_t ev) override
    {
        return ModEventHelper(fd, ev, EPOLL_CTL_MOD);
    }
    bool DelEvent(int fd) override
    {
        return 0 == epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, nullptr);
    }

    int Wait(struct epoll_event revs[], int size, int timeout)
    {
        return ::epoll_wait(_epfd, revs, size, timeout);
    }
    ~Epoller() {}

private:
    int _epfd;
};
